import 'dart:convert';
import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class BackgroundThreadApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: BackgroundThreadAppPage(),
    );
  }
}

class BackgroundThreadAppPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _BackgroundThreadAppPageState();
}

class _BackgroundThreadAppPageState extends State<BackgroundThreadAppPage> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    loadData();
  }

  showLoadingDialog() {
    if (widgets.length == 0) {
      return true;
    }
    return false;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getListView();
    }
  }

  getProgressDialog() {
    return Center(
      child: CircularProgressIndicator(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: getBody(),
    );
  }

  ListView getListView() => ListView.builder(
      itemCount: widgets.length,
      itemBuilder: (BuildContext context, int position) {
        return getRow(position);
      });

  Widget getRow(int position) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Text("Row ${widgets[position]["title"]}"),
    );
  }

  loadData() async {
    // 获取接收端口
    ReceivePort receivePort = ReceivePort();
    // 等待分离结果
    await Isolate.spawn(dataLoader, receivePort.sendPort);
    // 获取到发送的第一条信息
    SendPort sendPort = await receivePort.first;
    // 获取列表
    List msg = await sendReceive(
        sendPort, "https://jsonplaceholder.typicode.com/posts");
    setState(() {
      widgets = msg;
    });
  }

  static dataLoader(SendPort sendPort) async {
    // 获取接收端口
    ReceivePort port = ReceivePort();
    // 发送
    sendPort.send(port.sendPort);
    // 等待结果
    await for (var msg in port) {
      // 获取URL
      String data = msg[0];
      // 发送器
      SendPort replyTo = msg[1];
      http.Response response = await http.get(data);
      // 解析JSON
      replyTo.send(json.decode(response.body));
    }
  }

  Future sendReceive(SendPort port, msg) {
    ReceivePort response = ReceivePort();
    port.send([msg, response.sendPort]);
    return response.first;
  }
}
